import {
  DRAG_END_EVENT,
  SELECT_COMPONENT_EVENT,
  CHANGE_TAB_EVENT,
  SCROLL_EVENT
} from '../common/event'
import { generateCID, getComponentIndexByCID } from '../common/util'
export const containerMixin = {
  props: {
    isRoot: {
      type: Boolean,
      default: false
    },
    item: {
      default() {
        return {
          children: []
        }
      }
    }
  },
  data() {
    return {
      cid: generateCID(),
      components: this.item.children || [],
      domArr: [],
      curIndex: null,
      scrollTop: 0,
      scrollLeft: 0,
      area: {
        left: 0,
        top: 0,
        right: 0,
        bottom: 0,
      },
      containerCls: 'kw-component-container'
    }
  },
  watch: {
    components(val) {
      this.$emit('on-update', val)
    },
    item(val) {
      this.components = val.children || []
    }
  },
  created() {
    this.$root.EventBus.$on(SCROLL_EVENT, (obj) => {
      this.scrollTop = obj.scrollTop
      this.scrollLeft = obj.scrollLeft
      this.updateArea()
    })
  },
  mounted: function () {
    this.updateArea()
  },
  updated: function () {
    this.$nextTick(()=> {
      this.updateArea()
    })
  },
  methods: {
    updateArea() {
      if (!this.$refs.container) {
        return
      }
      let dom = this.$refs.container
      let actualLeft = dom.offsetLeft
      let actualTop = dom.offsetTop
      let current = dom.offsetParent
      while (current !== null) {
        actualLeft += current.offsetLeft
        actualTop += current.offsetTop
        current = current.offsetParent
      }
      if (!this.isRoot) {
        actualTop -= this.scrollTop
        actualLeft -= this.scrollLeft
      }
      this.area.left = actualLeft
      this.area.top = actualTop
      this.area.right = actualLeft + dom.offsetWidth
      this.area.bottom = actualTop + dom.offsetHeight

      this.domArr = []
      let el = this.$refs.container
      let domArr = []
      // domArr = el.querySelectorAll('.kw-component') // 这种方式会获取所有节点（包含子容器内节点）
      let domBody = el.querySelector('.container-widget-body')
      for (let i = 0; i < domBody.children.length; i++) { // 这种方式结构变后要跟着调整
        let child = domBody.children[i]
        let cc = child.children[0]
        if (cc) {
          domArr.push(cc)
        }
      }
      for (let i = 0, l = domArr.length; i < l; i++) {
        let dom = domArr[i]
        let top = dom.offsetTop
        let height = dom.offsetHeight
        let left = dom.offsetLeft
        let width = dom.offsetWidth
        if (this.isRoot) {
          top -= this.scrollTop
          left -= this.scrollLeft
        }
        this.domArr.push({
          width: width,
          height: height,
          top: top,
          bottom: (top + height) >> 0,
          left: left,
          right: (left + width) >> 0,
          mh: (top + height / 2) >> 0,
          mw: (left + width / 2) >> 0,
          classList: dom.classList,
          cid: dom.getAttribute('cid')
        })
      }
      this.$emit('on-updated', this.domArr.length)
    },
    moveInCanvas(obj) {
      this.curIndex = null
      // 当鼠标在中间可拖动区域
      if (obj.clientX >= this.area.left && obj.clientX <= this.area.right &&
        obj.clientY >= this.area.top && obj.clientY <= this.area.bottom) {
        // 鼠标距离可拖动区域顶部的距离
        let distTop = obj.clientY - this.area.top
        // let distLeft = obj.clientX - this.area.left
        let domCount = this.domArr.length
        let item = null
        let j = 0
        for (let i = 0; i < domCount; i++) {
          item = this.domArr[i]
          if (distTop < item.bottom && this.isContainerWidget(distTop, item, obj)) {
            return;
          }
          if (distTop > item.mh) {
            j = i + 1
            if (j < domCount) {
              if (distTop <= this.domArr[j].mh) {
                this.curIndex = j
              }
            } else {
              this.curIndex = j
            }
          }
        }

        this.curIndex = this.curIndex || 0
      }
    },
    moveEnd(obj) {
      this.$root.EventBus.$emit(DRAG_END_EVENT, obj)
      obj.componentView.draging = null
      if (this.curIndex !== null) {
        this.removeComponent(obj)
        let component = JSON.parse(JSON.stringify(obj))
        let componentView = component.componentView
        if (!componentView.cid) {
          component.componentView.cid = generateCID()
        }
        component.componentView.pid = this.cid
        this.components.splice(this.curIndex, 0, component.componentView)
        this.$set(component.componentView, 'selected', true)
        this.curIndex = null
        this.$root.EventBus.$emit(CHANGE_TAB_EVENT, true)
        this.$root.EventBus.$emit(SELECT_COMPONENT_EVENT, component.componentView)
      } else {
        this.toggleChildren(obj, 'moveEnd')
      }
    },
    removeComponent(obj) {
      if (this.cid === obj.componentView.pid) {
        // 如果拖拽控件为当前容器控件
        let index = getComponentIndexByCID(this.components, obj.componentView.cid)
        if (index > -1) {
          this.components.splice(index, 1)
        }
      } else {
        this.toggleChildren(obj, 'removeComponent')
      }
    },
    selectComponent(obj) {
      this.components.map(o => {
        if (obj.cid !== o.cid) {
          o.selected = false
        }
      })
      this.toggleChildren(obj, 'selectComponent')
    },
    changeComponent(obj) {
      if (obj.pid === this.cid) {
        this.components.every((o, i) => {
          if (o.cid === obj.cid) {
            this.components.splice(i, 1, obj)
            return false
          }
          return true
        })
      } else {
        this.toggleChildren(obj, 'changeComponent')
      }
    },
    toggleChildren(obj, strFun) {
      this.$children.map(child => {
        try {
          if (child.$el.classList.contains(this.containerCls)) {
            child.$children.map(cc=> {
              if (cc[strFun]) {
                cc[strFun](obj)
              }
            })
          }
        } catch (error) {
          console.log(error)
        }
      })
    },
    isContainerWidget(distTop, item, obj) {
      if (distTop > item.top && distTop < item.bottom) {
        if (item.classList.contains(this.containerCls)) {
          if (item.cid !== obj.componentView.cid) {
            this.curIndex = null
            this.toggleChildren(obj, 'moveInCanvas')
            return true
          }
        }
      }
      return false
    }
  }
}

export const widget = {
  props: {
    item: {
      default() {
        return {}
      }
    }
  }
}